﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
using JigLibX.Math;
using JigLibX.Physics;
using JigLibX.Geometry;
using JigLibX.Collision;
using TerrainGenerator.Geometry;

namespace TerrainGenerator.Physics
{
    class TerrainObject : PhysicsObject
    {
        BinaryTriangleTerrain btt;

        const int maxTrianglesPerCell = 16;
        const float minCellSize = 10.0f;

        public TerrainObject(Game game, BinaryTriangleTerrain btt)
            : base(Vector3.Zero, Vector3.One)
        {
            body = new Body();
            skin = new CollisionSkin(null);

            int width = btt.Trees.GetLength(0);
            int height = btt.Trees.GetLength(1);
            for (int x = 0; x < width; ++x)
            {
                for (int y = 0; y < height; ++y)
                {
                    BinaryTriangleTree tree = btt.Trees[x, y];
                    VertexPositionNormalColored[] treeVertices = tree.Vertices();
                    int[] treeIndices = tree.Indices();

                    List<Vector3> vertices = new List<Vector3>();
                    List<TriangleVertexIndices> indices = new List<TriangleVertexIndices>();
                    for (int i = 0; i < treeVertices.Length; ++i)
                    {
                        vertices.Add(treeVertices[i].Position);
                    }
                    for (int i = 0; i < treeIndices.Length - 2; i += 3)
                    {
                        indices.Add(new TriangleVertexIndices(treeIndices[i], treeIndices[i + 1], treeIndices[i + 2]));
                    }
                    TriangleMesh mesh = new TriangleMesh();
                    mesh.CreateMesh(vertices, indices, maxTrianglesPerCell, minCellSize);
                    skin.AddPrimitive(mesh, (int)(MaterialTable.MaterialID.NormalNormal));
                }
            }
            PhysicsSystem.CurrentPhysicsSystem.CollisionSystem.AddCollisionSkin(skin);
            this.btt = btt;
        }

        public void Draw(Matrix world, Matrix view, Matrix projection)
        {
            Matrix myWorld = world * GetWorldMatrix();
            btt.Draw(myWorld, view, projection);
        }

        public void Draw(Matrix world, Matrix view, Matrix projection, Vector3 viewVector, Effect effect)
        {
            Matrix myWorld = world * GetWorldMatrix();
            btt.Draw(myWorld, view, projection, viewVector, effect);
        }
    }
}
